iT邦幫忙

2021 iThome 鐵人賽

DAY 26
2

在上一篇Day 25 - Spring Security (二) UserDetailsService中有實作了UserDetailsService 進行基本的使用者資訊驗證,而實務上我們不會只簡單比對使用者名稱和密碼,還會檢查帳號狀態等資訊,因此我們這篇文章來實作自定義的AuthenticationProvider。

實作

調整SecurityConfig

package com.example.iThomeIronMan.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;

import com.example.iThomeIronMan.security.CustomAuthenticationFailureHandler;
import com.example.iThomeIronMan.security.CustomAuthenticationProvider;
import com.example.iThomeIronMan.security.CustomAuthenticationSuccessHandler;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private CustomAuthenticationProvider authProvider;
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// TODO Auto-generated method stub
		auth.authenticationProvider(authProvider);
	}

	// 忽略...

}

調整MemberAccountService

package com.example.iThomeIronMan.service.impl;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.iThomeIronMan.dao.MemberAccountDao;
import com.example.iThomeIronMan.model.Member;
import com.example.iThomeIronMan.model.MemberAccount;
import com.example.iThomeIronMan.service.MemberAccountService;
import com.example.iThomeIronMan.service.MemberService;
import com.example.iThomeIronMan.service.ex.AccountDuplicateException;
import com.example.iThomeIronMan.service.ex.InsertException;

@Service
public class MemberAccountServiceImpl implements MemberAccountService, UserDetailsService {

	// 忽略...

	public MemberAccount login(MemberAccount memberAccount) {
		
		// 檢查帳號是否存在
		MemberAccount data = memberAccountDao.getMemberAccountByAccount(memberAccount.getAccount());
		if(data == null) {
			return null;
		}

		// 比對密碼
		if(!passwordEncoder.matches(memberAccount.getPassword() + data.getSalt(), data.getPassword())) return null;

		return data;
	}

}

建立CustomAuthenticationProvider

package com.example.iThomeIronMan.security;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import com.example.iThomeIronMan.model.MemberAccount;
import com.example.iThomeIronMan.service.MemberAccountService;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

	@Autowired
	private MemberAccountService memberAccountService;
	
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		// TODO Auto-generated method stub
		String account = authentication.getName();
		String password = String.valueOf(authentication.getCredentials());
		
        try {
        	MemberAccount memberAccount = new MemberAccount();
        	memberAccount.setAccount(account);
        	memberAccount.setPassword(password);
        	memberAccount = memberAccountService.login(memberAccount);
        	        	
        	Collection<? extends GrantedAuthority> authorities = memberAccount.getAuthorities();
    		return new UsernamePasswordAuthenticationToken(memberAccount, password, authorities);	
        }
        catch(Exception e) {
        	e.printStackTrace();
        	return null;
        }
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return authentication.equals(UsernamePasswordAuthenticationToken.class);
	}

}

上一篇
Day 25 - Spring Security (二) UserDetailsService
下一篇
Day 27 - Spring Security (四) JWT
系列文
誤打誤撞學了Spring Boot 還當了後端工程師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言